
/**********************************************************************************
 *
 *	文件名称：StartGif.c
 * 	文件作用：运行此文件的函数可以将Gif动画显示到开机动画
 * 	文件作者：WSY
 * 	修改日期：2023.12.25
 *  	注意事项：
 *
 *	版权声明：CopyRight (c)  @cecelmx.126.com  All Right Reserved
 * ********************************************************************************/
#include "showImg.h"

/// @brief 调用开机动画函数，即可将开机目录下的gif动图显示出来
/// @return 返回1表示成功，-1则表示失败
int startGif()
{

    /*将开机动画文件夹显示出来*/
    P_Node start_head = NewNode(NULL);
    if (start_head == NULL)
    {
        printf("开机动画申请链表头失败!\n");
        return -1;
    }

    /*1.运行脚本后，可传递路径参数，调用函数读取传递路径，找到其所有图片文件*/
    // 函数findImg(),可将指定文件夹下的图片文件添加到链表
    int is_findImg = FindFile(STARTGIF_PATH, start_head);
    if (is_findImg <= 0)
    {
        printf("调用函数findImg失败!\n");
        return -1;
    }
    printf("图片数量为：%d\n", is_findImg);

    /*定义错误处理变量*/
    int is_read = 0;

    DisplayList(start_head);

    /*遍历链表看看，里面有啥*/

    /*遍历链表，将每一张图显示到页面*/
    for (P_Node tmp = start_head->Next; tmp != start_head; tmp = tmp->Next)
    {

        /*测试*/
        // 调用函数
        is_read = showImgJpg(tmp->Data.Name, // 链表里面的每一张图的路径传入
                             lcd_mmap,       // 传入映射地址
                             0,              // 起始start_x 设为 0
                             0,              // 起始start_y 设为 0
                             1);             // 将模式设置为 1 大图模式，也就是原图显示
        if (is_read <= 0)
        {
            printf("读取开机动画JPG图片失败\n");
            munmap(lcd_mmap, LCD_WIDTH * LCD_HEIGHT * 4);
            close(fb_lcd);
            return -1;
        }
        // 延时
        usleep(1000 * 30);
    }
    /*将链表资源释放掉*/
    printf("开机动画结束了，开始释放资源并退出!\n");
    DestroyNode(start_head);
    return 1;
}

/****************************************************************/
/// @brief 调用主界面动画函数，即可将主界面目录下的gif动图显示出来
/// @return 返回1表示成功，-1则表示失败
int mainGif()
{

    /*将开机动画文件夹显示出来*/
    P_Node main_head = NewNode(NULL);
    if (main_head == NULL)
    {
        printf("主界面动画申请链表头失败!\n");
        return -1;
    }

    /*1.运行脚本后，可传递路径参数，调用函数读取传递路径，找到其所有图片文件*/
    // 函数findImg(),可将指定文件夹下的图片文件添加到链表
    int is_findImg = FindFile(MAINGIF_PATH, main_head);
    if (is_findImg <= 0)
    {
        printf("调用函数findImg失败!\n");
        return -1;
    }
    printf("图片数量为：%d\n", is_findImg);

    /*定义错误处理变量*/
    int is_read = 0;

    DisplayList(main_head);

    /*遍历链表，将每一张图显示到页面*/
    for (P_Node tmp = main_head->Next; tmp != main_head; tmp = tmp->Next)
    {

        /*测试*/
        // 调用函数
        is_read = showImgJpg(tmp->Data.Name, // 链表里面的每一张图的路径传入
                             lcd_mmap,       // 传入映射地址
                             0,              // 起始start_x 设为 0
                             0,              // 起始start_y 设为 0
                             1);             // 将模式设置为 1 大图模式，也就是原图显示
        if (is_read <= 0)
        {
            printf("读取主界面动画JPG图片失败\n");
            munmap(lcd_mmap, LCD_SIZE);
            close(fb_lcd);
            return -1;
        }
        // 延时
        usleep(1000 * 30);
    }
    /*将链表资源释放掉*/
    printf("主函数动画结束了，开始释放资源并退出!\n");
    DestroyNode(main_head);
    return 1;
}

/****************************************************************/
/// @brief 调用登录函数，即可将登录目录下的gif动图显示出来
/// @return 返回1表示成功，-1则表示失败
int loginGif()
{

    /*将开机动画文件夹显示出来*/
    P_Node login_head = NewNode(NULL);
    if (login_head == NULL)
    {
        printf("主界面动画申请链表头失败!\n");
        return -1;
    }

    /*1.运行脚本后，可传递路径参数，调用函数读取传递路径，找到其所有图片文件*/
    // 函数findImg(),可将指定文件夹下的图片文件添加到链表
    int is_findImg = FindFile(LOGIN_PATH, login_head);
    if (is_findImg <= 0)
    {
        printf("调用函数findImg失败!\n");
        return -1;
    }
    printf("图片数量为：%d\n", is_findImg);

    /*定义错误处理变量*/
    int is_read = 0;

    /*申请一个文件链表来供登录或者注册用*/
    P_UserNode user_head = NewUserNode(NULL);
    int file_Num = FindFile(USER_PATH, user_head);
    printf("fileNum : %d \n",file_Num);

    /*查看链表有多少个文件*/
    // DisplayList(login_head);

    DisplayUserList(user_head);

    /*调用pipg函数创建匿名管道，得到两个描述符，第一个是读端，第二个是写端*/
    int pipid[2]; /*定义数组准备接受两个描述符*/
    if (pipe2(pipid, O_NONBLOCK) == -1)
    {
        perror("创建管道失败!\n");
        return -1;
    }
    /* 调用fork()函数新建子进程，并获取其返回值 */
    int if_fork = fork();

    /*对返回值进行判断，如果是1，则表示当前在父进程 */
    /*对返回值进行判断，如果是0，则表示当前在子进程 */
    /*对返回值进行判断，如果是-1，则表示创建失败 */
    if (if_fork >= 1)
    {
        while (1)
        {
            /*遍历链表，直接死循环，除非子进程获取到合适的信息返回，不然gif循环展示*/
            for (P_Node tmp = login_head->Next; tmp != NULL; tmp = tmp->Next)
            {

                char if_long = '0'; /*新建变量判断结束，如果为1或者2，则表示已点击到指定位置，结束掉循环*/
                int is_read = read(pipid[0], &if_long, 1);

                if (if_long == '1')
                {

                    wait(NULL); /*如果是父进程打印读取管道信息，并等待儿子结束，然后退出*/

                    /*将链表资源释放掉*/
                    printf("登录动画结束了，开始释放资源并退出!\n");
                    DestroyNode(login_head);

                    /*跳转登录界面函数*/
                    printf("go to login!");
 
                    loginUser(user_head);   /*跳转登录界面*/
                    

                    return 1;
                }
                else if (if_long == '2')
                {

                    wait(NULL); /*如果是父进程打印读取管道信息，并等待儿子结束，然后退出*/

                    /*将链表资源释放掉*/
                    printf("登录动画结束了，开始释放资源并退出!\n");

                    DestroyNode(login_head);

                    /*跳转注册界面函数*/
                    printf("go to creat!");

                    creatUser(user_head) ;                          /*跳转注册界面*/

                    return 1;
                }
                else
                {
                    // 调用函数
                    is_read = showImgJpg(tmp->Data.Name, // 链表里面的每一张图的路径传入
                                         lcd_mmap,       // 传入映射地址
                                         0,              // 起始start_x 设为 0
                                         0,              // 起始start_y 设为 0
                                         1);             // 将模式设置为 1 大图模式，也就是原图显示
                    if (is_read <= 0)
                    {
                        printf("读取主界面动画JPG图片失败\n");
                        munmap(lcd_mmap, LCD_SIZE);
                        close(fb_lcd);
                        return -1;
                        break;
                    }
                    // 延时
                    usleep(1000 * 20);
                    // continue;    /*打开一张图片后，继续下一次循环*/
                }
            }
        }
    }
    else if (if_fork == 0)
    {
        /*调用获取坐标函数,获取触摸屏坐标*/
        struct absVa hh = {0};
        while (1)
        {
            hh = getAbsVa(); /*获取用户点击坐标*/
            printf("(%d,%d)\n", hh.va_x, hh.va_y);

            if (ifChiek(520, 700, 50, 200, hh.va_x, hh.va_y))
            {
                char if_long = '1';
                write(pipid[1], &if_long, 1); /*如果点击了了登录界面，往管道写入模式1*/
                break;
            }
            else if (ifChiek(510, 700, 280, 440, hh.va_x, hh.va_y))
            {
                char if_long = '2';
                write(pipid[1], &if_long, 1); /*如果点击了了注册界面，往管道写入模式2*/
                break;
            }
            else
            {
                continue; /*如果没有点击这两个地方，则继续获取坐标*/
            }
        }

        /*如果是子进程打印其pid和父pid*/
        printf("子进程结束\n");
        printf("chile exit !\n");

        DestroyNode(login_head);
        return 0;
    }
    else
    {
        perror("创建失败！\n");
    }

    return 1;
}